home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v17n02 / realprot.asc < prev    next >
Encoding:
Text File  |  1992-01-23  |  28.6 KB  |  790 lines

  1. _MIXING REAL- AND PROTECTED-MODE CODE_
  2. by Kerry Loynd
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7.  
  8. /*********************************************************************
  9.  * Filename.......  APIBTRV.C  Version........  1.2
  10.  * Author.........  Kerry Loynd
  11.  * Comments.......  WatCom C interface to the Btrieve Record Manager
  12.  This particular incarnation of the BTRV call interface is for the 32-bit 
  13.  Watcom compiler, and uses int386() to generate calls to BTRIEVE from programs 
  14.  operating in protected mode under Pharlap's 386|DOS. To compile it use 
  15.  the command line
  16.         C> WCL386 switcher.c apibtrv.c -l=<pharlap path>dosx32
  17.  To run the application use
  18.         C> BTRIEVE
  19.         C> RUN386 -callbuf n switcher <btrFile>
  20.  where n is size, in KBytes, of the intermode call buffer. The size of that 
  21.  buffer must be greater than or equal to the size of the XBUFFER struct plus 
  22.  the maximum data record size used by your program. BtrFile is the name of the 
  23.  data file you want to use with the application. Use 1 for this application.
  24.     There is a subtle point here that you must watch. ALWAYS pass all the 
  25.  defined parameters to a call to BTRV. Be especially careful to set *dataLen 
  26.  to 0 if it is not used in the operation you are performing. Otherwise, you 
  27.  may find that your program has gone over the wall...
  28.     I could have placed a check for an oversize dataLen and returned a status 
  29.  code, but, since I can't guarantee whether Novell will use the same status 
  30.  code some time in the future, I did not. NOTE: You should be aware that 
  31.  Watcom's linker will not successfully search DOSX32.LIB unless you use 
  32.  Watcom's librarian to extract all the object modules and then re-insert them 
  33.  into the library. If you want to understand why, call Watcom or Pharlap.
  34.  * COPYRIGHT (C) 1991.  All Rights Reserved.
  35.  * Kerry Loynd  Seattle, WA
  36.  ********************************************************************/
  37.  
  38. #include <stddef.h>
  39. #include <dos.h>
  40. #include <string.h>
  41.  
  42. typedef unsigned short int INT;
  43. typedef unsigned long int UINT;
  44. typedef unsigned long ULONG;
  45. typedef unsigned long REAL_ADDR; /* used for real-mode addresses. */
  46. typedef unsigned char UCHAR;     /* unsigned 8-bit value */
  47. typedef UCHAR far * FARPTR;
  48.  
  49. #define SINT short
  50. #define BTR_ERR     20      /* record manager not started */
  51. #define BTR_INT     0x7B    /* Btrieve interrupt vector */
  52. #define BTR_OFFSET  0x33    /* Btrieve offset within segment */
  53. #define VARIABLE_ID 0x6176  /* id for variable length records */
  54.  
  55. /* INT_BLOCK is a structure used by 386|DOS to invoke real mode interrupts. */
  56. typedef struct intblock {
  57.     SINT intNumber;          /* Interrupt to invoke. */
  58.     SINT rds;                /* real mode ds. */
  59.     SINT res;                /* real mode es. */
  60.     SINT rfs;                /* real mode fs. */
  61.     SINT rgs;                /* real mode gs. */
  62.     unsigned long reax;      /* real mode eax. */
  63.     unsigned long redx;      /* real mode edx. */
  64. } INT_BLOCK;
  65.  
  66. /* Whatever compiler you use, this structure must be byte aligned. */
  67. typedef struct BTRIEVE_PARMS /* structure passed to Btrieve Rec Mgr */
  68.  {
  69.    REAL_ADDR bufAddress;  /* caller's data buffer real mode address */
  70.    INT       bufLength;   /* length of data buffer */
  71.    REAL_ADDR curAddress;  /* user position block real mode address */
  72.    REAL_ADDR fcbAddress;  /* Real mode address of disk FCB */
  73.    INT       function;    /* requested function */
  74.    REAL_ADDR keyAddress;  /* Real mode address of user's key buffer */
  75.    char      keyLength;   /* length of user's key buffer */
  76.    char      keyNumber;   /* key of reference for request */
  77.    REAL_ADDR statAddress; /* Real mode address of status word */
  78.    INT       xfaceID;     /* language identifier */
  79.  } BTR_PARMS;
  80. typedef struct xbuffer {     /* Structure of intermode call buffer. */
  81.     BTR_PARMS xData;         /* Btrieve parameter block. */
  82.     INT stat;                /* status of Btrieve call */
  83.     char posBlock[128];      /* Btrieve file control block */
  84.     char keyBuff[255];       /* key buffer for this Btrieve file. */
  85.     char dataBuffer[1];      /* Data buffer space. */
  86. } XBUFFER;
  87.  
  88. // The following function prototypes are copied from pharlap.h. They have to 
  89. // be declared with cdecl because they expect their parameters on the stack.
  90. extern int cdecl DX_RMIV_GET(UINT, REAL_ADDR *);
  91. extern int cdecl DX_REAL_INT(INT_BLOCK *);
  92. extern int cdecl DX_RMLINK_GET(REAL_ADDR *, REAL_ADDR *, ULONG *, FARPTR *);
  93.  
  94. SINT cdecl BTRV (SINT operation,
  95.            UCHAR *posBlock,
  96.            char *dataBuf,
  97.            INT  *dataLen,
  98.            char *keyBuf,
  99.            SINT  keyNum
  100.           )
  101. {
  102. XBUFFER far *xbuff;
  103. SINT realSeg;
  104. SINT realOffset;
  105. REAL_ADDR realAddr;
  106. REAL_ADDR DOS386RealProc;
  107. ULONG buffSize;
  108. INT_BLOCK callBlock;
  109.  
  110. /*  Check to see that the Btrieve Record Manager has been started.  */
  111.   DX_RMIV_GET (BTR_INT, &realAddr);  /* Get real-mode int vector.   */
  112.   if ((realAddr & 0xFFFF) != BTR_OFFSET)  /* is Btrieve installed?  */
  113.      return (BTR_ERR);
  114. /* Get the real and protected addresses of the call buffer. */
  115. /* DOS386RealProc and buffSize are not used.                */
  116.  DX_RMLINK_GET (&DOS386RealProc, &realAddr, &buffSize,
  117.       (FARPTR *)&xbuff);
  118.   realSeg = (realAddr >> 16) & 0xFFFF; /* real-mode segment. */
  119.   realOffset = realAddr & 0xFFFF;      /* real-mode offset.  */
  120. /* Get the key and data info from the caller. */
  121.   _fmemcpy (xbuff->posBlock, (char far *)posBlock, 128);
  122.   _fmemcpy (xbuff->keyBuff, (char far *)keyBuf, 255);
  123.   _fmemcpy (xbuff->dataBuffer, (char far *)dataBuf, *dataLen);
  124. /*  Move user parameters to xbuff, where Btrieve can find them.     */
  125.   xbuff->stat = 0;
  126.   xbuff->xData.function    = operation;
  127.   xbuff->xData.statAddress = realAddr + offsetof (XBUFFER,stat);
  128.   xbuff->xData.fcbAddress  = realAddr + offsetof (XBUFFER,posBlock);
  129.   xbuff->xData.curAddress  = xbuff->xData.fcbAddress + 38;
  130.   xbuff->xData.bufAddress  = realAddr + offsetof (XBUFFER,dataBuffer);
  131.   xbuff->xData.bufLength   = *dataLen;
  132.   xbuff->xData.keyAddress  = realAddr + offsetof (XBUFFER, keyBuff);
  133.   xbuff->xData.keyLength   = 255;  /* use max since we don't know */
  134.   xbuff->xData.keyNumber   = keyNum;
  135.   xbuff->xData.xfaceID     = VARIABLE_ID;
  136.  
  137. /*  Make call to the Btrieve Record Manager.                        */
  138. /* Set up for Extended DOS call. Put real-mode interrupt call data into 
  139. the call block. */
  140.   callBlock.intNumber = BTR_INT;
  141.   callBlock.rds = realSeg;
  142.   callBlock.redx = realOffset;
  143.   DX_REAL_INT (&callBlock);  /* Issue real mode int, regs specified.*/
  144.   *dataLen = xbuff->xData.bufLength;
  145. /* Copy the key and data info back to the caller. */
  146.   _fmemcpy ((char far *)posBlock, xbuff->posBlock, 128);
  147.   _fmemcpy ((char far *)keyBuf, xbuff->keyBuff, 255);
  148.   _fmemcpy ((char far *)dataBuf, xbuff->dataBuffer, *dataLen);
  149.   return (xbuff->stat);   /* return status */
  150. }
  151.  
  152.  
  153.  
  154. [LISTING TWO]
  155.  
  156.  
  157. // Switcher.c 
  158. // This code should be easily portable to compilers other than Watcom's
  159.  
  160. #include <stdio.h>
  161. #include <stddef.h>
  162. #include <process.h>
  163. #include <ctype.h>
  164. #include <string.h>
  165. #include "btrv_def.h"
  166. #include "btrverrs.h"
  167.  
  168. #define SINT short
  169. typedef unsigned char UCHAR;    /* unsigned 8-bit value */
  170.  
  171. extern SINT cdecl BTRV (int, UCHAR *, char *, int *, char *, int);
  172.  
  173. /* CREATE_STRUCT is used to create the card file. */
  174. typedef struct tagCREATE_STRUCT {
  175.     FILE_SPEC fileInfo;
  176.     KEY_SPEC keyInfo;
  177. } CREATE_STRUCT;
  178. /* CARD_STRUCT is the structure of the card file records */
  179. typedef struct tagCARD_STRUCT {
  180.     char name[21];
  181.     char address[21];
  182.     char city[21];
  183. } CARD_STRUCT;
  184. #define CARD_LEN sizeof (CARD_STRUCT)
  185. #define NAME_KEY 0
  186. static unsigned char posBlock[128];  /* Btrieve's position control */
  187. static char searchKey[255]; /* Search key buffer. MUST be 255 long.*/
  188. static CREATE_STRUCT cardInfo = {
  189.     sizeof(CARD_STRUCT), 1024, 1, 0L, NO_FILE_FLAGS, 0, 0,
  190.     1, 21, EXTENDED_TYPE_KEY | MODIFIABLE_KEY, 1L, ZSTRING_KEY, 0, 0, 0, 0, 0
  191. };
  192. static void EditRecord (CARD_STRUCT *card)
  193. {
  194.     char done = 'n';
  195.     char gunkCatcher[80];
  196.     while (done != 'y') {
  197.         gets(gunkCatcher);  /* Flush out the input buffer. */
  198.         printf ("\n\nName: %s\n:", card->name);
  199.         flushall ();
  200.         gets (card->name);
  201.         printf ("\nAddress: %s\n:", card->address);
  202.         flushall ();
  203.         gets (card->address);
  204.         printf ("\nCity: %s\n:", card->city);
  205.         flushall ();
  206.         gets (card->city);
  207.         printf ("\n%-21s, %-21s, %-21s\n", card->name,
  208.           card->address, card->city);
  209.         printf ("\n\nDone? [y/n] ");
  210.         flushall ();
  211.         done = tolower (getchar());
  212.         printf ("Done = |%c|\n", done);
  213.     }
  214. }
  215. static void CreateRecord (void)
  216. {
  217.     CARD_STRUCT card;
  218.     int rc = 0;
  219.     int len = CARD_LEN;
  220.     memset (&card, '\0', sizeof (CARD_STRUCT));
  221.     EditRecord (&card);
  222.     rc = BTRV (INSERT_BTR, &posBlock[0], (char *)&card, &len,
  223.         searchKey, NAME_KEY);
  224.     if (rc != 0)
  225.     printf ("Could not insert record %s, BTRV error %d\n",
  226.         card.name, rc);
  227. }
  228. static void FindRecord (void)
  229. {
  230.     CARD_STRUCT card;
  231.     int rc = 0;
  232.     int len = CARD_LEN;
  233.     gets (searchKey); /* Flush out the input buffer. */
  234.     printf ("Name to search on: ");
  235.     flushall ();
  236.     gets (searchKey);
  237.     rc = BTRV (GET_GT_EQ, &posBlock[0], (char *)&card, &len, 
  238.         searchKey, NAME_KEY);
  239.     if (rc == 0) {
  240.         printf ("Found %s.\n\nEdit this record?", searchKey);
  241.         if (tolower(getchar ()) == 'y') {
  242.             EditRecord (&card);
  243.             rc = BTRV (UPDATE_BTR, &posBlock[0], (char *)&card, &len,
  244.                 searchKey, NAME_KEY);
  245.             if (rc != 0)
  246.                 printf ("Could not insert record %s, BTRV error %d\n",
  247.                     card.name, rc);
  248.         }
  249.     } else
  250.         printf ("Could not find a record.\n");
  251. }
  252. static void ListRecords ()
  253. {
  254.     CARD_STRUCT card;
  255.     int rc = 0;
  256.     int len = CARD_LEN;
  257.     printf ("\n\nList of records:\n\n");
  258.     rc = BTRV (GET_FIRST, &posBlock[0], (char *)&card, &len,
  259.         searchKey, NAME_KEY);
  260.     while (rc == 0) {
  261.         printf ("%-21s, %-21s, %-21s\n", card.name, card.address,
  262.             card.city);
  263.         len = CARD_LEN;
  264.         rc = BTRV (GET_GT, &posBlock[0], (char *)&card, &len,
  265.             searchKey, NAME_KEY);
  266.     }
  267.     if (rc != END_OF_FILE_BTR)
  268.     printf ("\n\nBTRV error %d\n", rc);
  269.     printf ("Press any key to continue.\n");
  270.     while (!kbhit()); /* wait for a key */
  271.     getch (); /* clean out the dregs. */
  272. }
  273. int main (int argc, char **argv)
  274. {
  275.     int rc = 0;
  276.     int menuChoice = 0;
  277.     int len = 0;
  278.     char fakeData[1];
  279.     if (argc < 2) {
  280.         printf ("No card file specified.\n");
  281.         exit(1);
  282.     }
  283.     strcpy (searchKey, argv[1]);
  284.     rc = BTRV (OPEN_BTR, &posBlock[0], fakeData, &len, searchKey,
  285.         ACCELERATED);
  286.     if (rc == BTRIEVE_INACTIVE_BTR) {
  287.         printf ("Btrieve isn't loaded.\n");
  288.         exit(1);
  289.     }
  290.     if (rc !=  0) {
  291.         len = sizeof(CREATE_STRUCT);
  292.         rc = BTRV (CREATE_BTR, &posBlock[0], (char *)&cardInfo, &len,
  293.             searchKey, NAME_KEY);
  294.         if (rc != 0) {
  295.             printf ("BTRV create returned %d\n", rc);
  296.             BTRV( STOP_BTR, &posBlock[0], fakeData, &len, fakeData,
  297.                 NAME_KEY);
  298.             exit (1);
  299.         }
  300.         len = 0;
  301.         rc = BTRV (OPEN_BTR, &posBlock[0], fakeData, &len, searchKey, 
  302.             ACCELERATED);
  303.         if (rc != 0) {
  304.             printf ("BTRV open returned %d\n", rc);
  305.             BTRV( STOP_BTR, &posBlock[0], fakeData, &len, fakeData, NAME_KEY);
  306.             exit (1);
  307.         }
  308.     }
  309.     menuChoice = 0;
  310.     while (menuChoice != 9) {
  311.         printf ("\n\n1. Find a record\n");
  312.         printf ("2. Create a new record\n");
  313.         printf ("3. List records\n");
  314.         printf ("9. Exit\n\n:");
  315.         scanf ("%d", &menuChoice);
  316.         switch (menuChoice) {
  317.             case 1:
  318.                 FindRecord ();
  319.                 break;
  320.             case 2:
  321.                 CreateRecord ();
  322.                 break;
  323.             case 3:
  324.                 ListRecords ();
  325.                 break;
  326.         }
  327.     }
  328.     BTRV (CLOSE_BTR, &posBlock[0], fakeData, &len, searchKey,
  329.         NAME_KEY);
  330.     BTRV( STOP_BTR, &posBlock[0], fakeData, &len, searchKey,
  331.         NAME_KEY);
  332.     return 0;
  333. }
  334.  
  335.  
  336.  
  337. [LISTING THREE]
  338.  
  339.  
  340.  
  341. /*********************************************************************
  342.  * Filename.......  386BTRV.C
  343.  * Version........  1.2
  344.  * Version Date...  August 8, 1991
  345.  * Author.........  Kerry Loynd
  346.  * Comments.......  WatCom C interface to the Btrieve Record Manager
  347.  
  348.     This particular incarnation of the BTRV call interface is for the
  349.     32-bit Watcom compiler, and uses Pharlap API library calls to
  350.     generate calls to BTRIEVE from programs operating in protected
  351.     mode under Pharlap's 386|DOS.  To compile it use the command line
  352.         
  353.         C> WCL386 switcher.c apibtrv.c -l=<pharlap path>dosx32
  354.     
  355.     To run the application use
  356.  
  357.         C> BTRIEVE
  358.         C> RUN386 switcher <btrFile>
  359.  
  360.     where n is the size, in KBytes, of the intermode call buffer.  The
  361.     size of that buffer must be greater than or equal to the size of
  362.     the XBUFFER struct plus the maximum data record size used by your
  363.     program.  BtrFile is the name of the data file you want to use
  364.     with the application.  Use 1 for this application.
  365.  
  366.     There is a subtle point here that you must watch.  ALWAYS pass all
  367.     the defined parameters to a call to BTRV.  Be especially careful
  368.     to set *dataLen to 0 if it is not used in the operation you are
  369.     performing.  Otherwise, you may find that your program has gone
  370.     over the wall...
  371.  
  372.     I could have placed a check for an oversize dataLen and returned
  373.     a status code, but, since I can't guarantee whether Novell will
  374.     use the same status code some time in the future, I did not.
  375.  
  376.     NOTE: You should be aware that Watcom's linker will not
  377.     successfully search DOSX32.LIB unless you use Watcom's librarian
  378.     to extract all the object modules and then re-insert them into the
  379.     library.  If you want to understand why, call Watcom or Pharlap.
  380.  
  381.  *
  382.  * COPYRIGHT (C) 1991.  All Rights Reserved.
  383.  * Kerry Loynd  Seattle, WA
  384.  * (206)624-7970
  385.  ********************************************************************/
  386.  
  387. #include <stddef.h>
  388. #include <dos.h>
  389. #include <string.h>
  390.  
  391. typedef unsigned short int INT;
  392. typedef unsigned long int UINT;
  393. typedef unsigned long ULONG;
  394. typedef unsigned long REAL_ADDR; /* used for real-mode addresses. */
  395. typedef unsigned char UCHAR;     /* unsigned 8-bit value */
  396. typedef UCHAR far * FARPTR;
  397.  
  398. #define SINT short
  399. #define BTR_ERR     20      /* record manager not started */
  400. #define BTR_INT     0x7B    /* Btrieve interrupt vector */
  401. #define BTR_OFFSET  0x33    /* Btrieve offset within segment */
  402. #define VARIABLE_ID 0x6176  /* id for variable length records */
  403.  
  404. /*
  405.    INT_BLOCK is a structure used by 386|DOS to invoke real mode
  406.    interrupts.
  407. */
  408. typedef struct intblock {
  409.     SINT intNumber;          /* Interrupt to invoke. */
  410.     SINT rds;                /* real mode ds. */
  411.     SINT res;                /* real mode es. */
  412.     SINT rfs;                /* real mode fs. */
  413.     SINT rgs;                /* real mode gs. */
  414.     unsigned long reax;      /* real mode eax. */
  415.     unsigned long redx;      /* real mode edx. */
  416. } INT_BLOCK;
  417.  
  418.  
  419. /* Whatever compiler you use, this structure must be byte aligned. */
  420.  
  421. typedef struct BTRIEVE_PARMS /* structure passed to Btrieve Rec Mgr */
  422.  {
  423.    REAL_ADDR bufAddress;  /* caller's data buffer real mode address */
  424.    INT       bufLength;   /* length of data buffer */
  425.    REAL_ADDR curAddress;  /* user position block real mode address */
  426.    REAL_ADDR fcbAddress;  /* Real mode address of disk FCB */
  427.    INT       function;    /* requested function */
  428.    REAL_ADDR keyAddress;  /* Real mode address of user's key buffer */
  429.    char      keyLength;   /* length of user's key buffer */
  430.    char      keyNumber;   /* key of reference for request */
  431.    REAL_ADDR statAddress; /* Real mode address of status word */
  432.    INT       xfaceID;     /* language identifier */
  433.  } BTR_PARMS;
  434.  
  435. typedef struct xbuffer {     /* Structure of intermode call buffer. */
  436.     BTR_PARMS xData;         /* Btrieve parameter block. */
  437.     INT stat;                /* status of Btrieve call */
  438.     char posBlock[128];      /* Btrieve file control block */
  439.     char keyBuff[255];       /* key buffer for this Btrieve file. */
  440.     char dataBuffer[1];      /* Data buffer space. */
  441. } XBUFFER;
  442.  
  443. // The following function prototypes are copied from pharlap.h.
  444. // They have to be declared with cdecl because they expect their
  445. // parameters on the stack.
  446. extern int cdecl DX_RMIV_GET(UINT, REAL_ADDR *);
  447. extern int cdecl DX_REAL_INT(INT_BLOCK *);
  448. extern int cdecl DX_RMLINK_GET(REAL_ADDR *, REAL_ADDR *, ULONG *,
  449.                                FARPTR *);
  450.  
  451. SINT cdecl BTRV (SINT operation,
  452.            UCHAR *posBlock,
  453.            char *dataBuf,
  454.            INT  *dataLen,
  455.            char *keyBuf,
  456.            SINT  keyNum
  457.           )
  458.  
  459. {
  460. XBUFFER far *xbuff;
  461. SINT realSeg;
  462. SINT realOffset;
  463. REAL_ADDR realAddr;
  464. REAL_ADDR DOS386RealProc;
  465. ULONG buffSize;
  466. INT_BLOCK callBlock;
  467.  
  468. /*                                                                  */
  469. /*  Check to see that the Btrieve Record Manager has been started.  */
  470. /*                                                                  */
  471.   DX_RMIV_GET (BTR_INT, &realAddr);  /* Get real-mode int vector.   */
  472.   if ((realAddr & 0xFFFF) != BTR_OFFSET)  /* is Btrieve installed?  */
  473.      return (BTR_ERR);
  474.  
  475. /* Get the real and protected addresses of the call buffer. */
  476. /* DOS386RealProc and buffSize are not used.                */
  477.  DX_RMLINK_GET (&DOS386RealProc, &realAddr, &buffSize,
  478.       (FARPTR *)&xbuff);
  479.   realSeg = (realAddr >> 16) & 0xFFFF; /* real-mode segment. */
  480.   realOffset = realAddr & 0xFFFF;      /* real-mode offset.  */
  481.  
  482. /* Get the key and data info from the caller. */
  483.   _fmemcpy (xbuff->posBlock, (char far *)posBlock, 128);
  484.   _fmemcpy (xbuff->keyBuff, (char far *)keyBuf, 255);
  485.   _fmemcpy (xbuff->dataBuffer, (char far *)dataBuf, *dataLen);
  486.  
  487. /*                                                                  */
  488. /*  Move user parameters to xbuff, where Btrieve can find them.     */
  489. /*                                                                  */
  490.   xbuff->stat = 0;
  491.   xbuff->xData.function    = operation;
  492.   xbuff->xData.statAddress = realAddr + offsetof (XBUFFER,stat);
  493.   xbuff->xData.fcbAddress  = realAddr + offsetof (XBUFFER,posBlock);
  494.   xbuff->xData.curAddress  = xbuff->xData.fcbAddress + 38;
  495.   xbuff->xData.bufAddress  = realAddr + offsetof (XBUFFER,dataBuffer);
  496.   xbuff->xData.bufLength   = *dataLen;
  497.   xbuff->xData.keyAddress  = realAddr + offsetof (XBUFFER, keyBuff);
  498.   xbuff->xData.keyLength   = 255;  /* use max since we don't know */
  499.   xbuff->xData.keyNumber   = keyNum;
  500.   xbuff->xData.xfaceID     = VARIABLE_ID;
  501.  
  502. /*                                                                  */
  503. /*  Make call to the Btrieve Record Manager.                        */
  504. /*                                                                  */
  505.  
  506. /*
  507.    Set up for the Extended DOS call.  Put the real-mode interrupt
  508.    call data into the call block.
  509. */
  510.   callBlock.intNumber = BTR_INT;
  511.   callBlock.rds = realSeg;
  512.   callBlock.redx = realOffset;
  513.   DX_REAL_INT (&callBlock);  /* Issue real mode int, regs specified.*/
  514.  
  515.   *dataLen = xbuff->xData.bufLength;
  516.  
  517. /* Copy the key and data info back to the caller. */
  518.   _fmemcpy ((char far *)posBlock, xbuff->posBlock, 128);
  519.   _fmemcpy ((char far *)keyBuf, xbuff->keyBuff, 255);
  520.   _fmemcpy ((char far *)dataBuf, xbuff->dataBuffer, *dataLen);
  521.  
  522.   return (xbuff->stat);   /* return status */
  523. }
  524.  
  525.  
  526.  
  527. [LISTING FOUR]
  528.  
  529. //BTRVERRS.H
  530. /* This file contains the error codes returned by Btrieve. */
  531.  
  532. #define SUCCESS_BTR                               0
  533. #define INVALID_OP_BTR                            1
  534. #define IO_ERROR_BTR                              2
  535. #define FILE_NOT_OPEN_BTR                         3
  536. #define KEY_NOT_FOUND_BTR                         4
  537. #define DUPLICATE_KEY_BTR                         5
  538. #define INVALID_KEY_NUM_BTR                       6
  539. #define DIFF_KEY_NUM_BTR                          7
  540. #define INVALID_POSITION_BTR                      8
  541. #define END_OF_FILE_BTR                           9
  542. #define MOD_KEY_ERROR_BTR                        10
  543. #define BAD_FILE_NAME_BTR                        11
  544. #define FILE_NOT_FOUND_BTR                       12
  545. #define EXT_FILE_ERROR_BTR                       13
  546. #define PREIMG_OPEN_ERR_BTR                      14
  547. #define PREIMG_IO_ERR_BTR                        15
  548. #define EXPANSION_ERROR_BTR                      16
  549. #define CLOSE_ERROR_BTR                          17
  550. #define DISK_FULL_BTR                            18
  551. #define UNRECOVERABLE_BTR                        19
  552. #define BTRIEVE_INACTIVE_BTR                     20
  553. #define KEY_BUFF_TOO_SHORT_BTR                   21
  554. #define DATA_BUFF_TOO_SHORT_BTR                  22
  555. #define POS_BLOCK_LEN_ERR_BTR                    23
  556. #define PAGE_SIZE_ERR_BTR                        24
  557. #define CREATE_IO_ERR_BTR                        25
  558. #define KEY_COUNT_ERR_BTR                        26
  559. #define INVALID_KEY_POS_BTR                      27
  560. #define INVALID_REC_LEN_BTR                      28
  561. #define INVALID_KEY_LEN_BTR                      29
  562. #define NOT_BTRIEVE_FILE_BTR                     30
  563. #define ALREADY_EXTENDED_BTR                     31
  564. #define EXTEND_IO_ERR_BTR                        32
  565. #define INVALID_EXT_NAME_BTR                     34
  566. #define DIR_ERROR_BTR                            35
  567. #define TRANSACTION_ERR_BTR                      36
  568. #define ACTIVE_TRANS_BTR                         37
  569. #define TRANSACT_CTL_IO_ERR_BTR                  38
  570. #define END_TRANSACT_ERR_BTR                     39
  571. #define TRANSACT_MAX_FILES_BTR                   40
  572. #define OP_NOT_ALLOWED_BTR                       41
  573. #define INCOMPLETE_ACCEL_ACCESS_BTR              42
  574. #define INVALID_REC_ACCESS_BTR                   43
  575. #define NULL_KEY_PATH_BTR                        44
  576. #define INCONSISTENT_KEY_FLAGS_BTR               45
  577. #define ACCESS_DENIED_BTR                        46
  578. #define MAX_FILES_OPEN_BTR                       47
  579. #define BAD_ALT_DEF_FILE_BTR                     48
  580. #define KEY_TYPE_ERR_BTR                         49
  581. #define OWNER_ALREADY_SET_BTR                    50
  582. #define INVALID_OWNER_BTR                        51
  583. #define CACHE_WRITE_ERR_BTR                      52
  584. #define BAD_INTERFACE_BTR                        53
  585. #define VARIABLE_PAGE_ERR_BTR                    54
  586. #define AUTOINCREMENT_ERR_BTR                    55
  587. #define INCOMPLETE_INDEX_BTR                     56
  588. #define EXP_MEMORY_ERR_BTR                       57
  589. #define SQUEEZE_BUFF_TOO_SHORT_BTR               58
  590. #define FILE_EXISTS_BTR                          59
  591. #define FILTER_LIMIT_REACHED_BTR                 64
  592. #define CONFLICT_BTR                             80
  593. #define LOCK_ERR_BTR                             81
  594. #define LOST_POSITION_BTR                        82
  595. #define READ_OUTSIDE_TRANSACT_BTR                83
  596. #define RECORD_IN_USE_BTR                        84
  597. #define FILE_IN_USE_BTR                          85
  598. #define FILE_TABLE_FULL_BTR                      86
  599. #define HANDLE_TABLE_FULL_BTR                    87
  600. #define BAD_OPEN_MODE_BTR                        88
  601. #define BAD_LOCK_TYPE_BTR                        93
  602. #define PERMISSION_ERR_BTR                       94
  603.  
  604.  
  605.  
  606. [LISTING FIVE]
  607.  
  608. //BTRV_DEF.H
  609. /* This file contains the manifest constants used to interface with Btrieve 
  610.  and the structures used to set up Btrieve files. */
  611.  
  612. #ifndef _BTRV_DEF_H_
  613. #define _BTRV_DEF_H_
  614.  
  615. #define OPEN_BTR                 0
  616. #define CLOSE_BTR                1
  617. #define INSERT_BTR               2
  618. #define UPDATE_BTR               3
  619. #define DELETE_BTR               4
  620. #define GET_EQUAL                5
  621. #define GET_NEXT                 6
  622. #define GET_PREVIOUS             7
  623. #define GET_GT                   8
  624. #define GET_GT_EQ                9
  625. #define GET_LT                  10
  626. #define GET_LT_EQ               11
  627. #define GET_FIRST               12
  628. #define GET_LAST                13
  629. #define CREATE_BTR              14
  630. #define GET_STATUS              15
  631. #define EXTEND_BTR              16
  632. #define SET_DIRECTORY           17
  633. #define GET_DIRECTORY           18
  634. #define BEGIN_TRANS             19
  635. #define END_TRANS               20
  636. #define ABORT_TRANS             21
  637. #define GET_POSITION            22
  638. #define GET_DIRECT              23
  639. #define STEP_NEXT               24
  640. #define STOP_BTR                25
  641. #define VERSION_BTR             26
  642. #define UNLOCK_BTR              27
  643. #define RESET_BTR               28
  644. #define SET_OWNER               29
  645. #define CLEAR_OWNER             30
  646. #define CREATE_SUPP_INDEX       31
  647. #define DROP_SUPP_INDEX         32
  648. #define STEP_FIRST              33
  649. #define STEP_LAST               34
  650. #define STEP_PREVIOUS           35
  651. #define GET_NEXT_EXTENDED       36
  652. #define GET_PREV_EXTENDED       37
  653. #define STEP_NEXT_EXTENDED      38
  654. #define STEP_PREV_EXTENDED      39
  655. #define INSERT_EXTENDED         40
  656. #define GET_KEY                 50
  657. #define SINGLE_WAIT_LOCK       100
  658. #define MULTIPLE_WAIT_LOCK     300
  659. #define SINGLE_NOWAIT_LOCK     200
  660. #define MULTIPLE_NOWAIT_LOCK   400
  661.  
  662. /* These are for key number options. */
  663. #define UNACCELERATED    0
  664. #define ACCELERATED     -1
  665. #define READ_ONLY       -2
  666. #define VERIFY          -3
  667.  
  668. /* Key flag bit definitions */
  669. #define NO_KEY_FLAGS            0x0000
  670. #define DUPLICATE_KEY           0x0001
  671. #define MODIFIABLE_KEY          0x0002
  672. #define BINARY_KEY              0x0004
  673. #define NULL_KEY                0x0008
  674. #define SEGMENTED_KEY           0x0010
  675. #define ALT_SORT_KEY            0x0020
  676. #define DESCENDING_KEY          0x0040
  677. #define SUPPLEMENTAL_KEY        0x0080
  678. #define EXTENDED_TYPE_KEY       0x0100
  679. #define MANUAL_KEY              0x0200
  680.  
  681. /* Extended key type definition bits */
  682. #define STRING_KEY               0
  683. #define INTEGER_KEY              1
  684. #define FLOAT_KEY                2
  685. #define DATE_KEY                 3
  686. #define TIME_KEY                 4
  687. #define DECIMAL_KEY              5
  688. #define MONEY_KEY                6
  689. #define LOGICAL_KEY              7
  690. #define NUMERIC_KEY              8
  691. #define BFLOAT_KEY               9
  692. #define LSTRING_KEY             10
  693. #define ZSTRING_KEY             11
  694. #define UNSIGNED_BINARY_KEY     14
  695. #define AUTOINCREMENT_KEY       15
  696.  
  697. /* File attribute bit definitions */
  698. #define NO_FILE_FLAGS           0x00
  699. #define VARIABLE_LENGTH_FILE    0x01
  700. #define TRUNCATE_BLANKS_FILE    0x02
  701. #define PREALLOCATION_FILE      0x04
  702. #define DATA_COMPRESSION_FILE   0x08
  703. #define KEY_ONLY_FILE           0x10
  704. #define FREE_SPACE_10_FILE      0x40
  705. #define FREE_SPACE_20_FILE      0x80
  706. #define FREE_SPACE_30_FILE      0xC0
  707.  
  708. #define     BTRV_EQ  1
  709. #define     BTRV_GT  2
  710. #define     BTRV_LT  3
  711. #define     BTRV_NE  4
  712. #define     BTRV_GE  5
  713. #define     BTRV_LE  6
  714. #define     BTRV_AND 1
  715. #define     BTRV_OR  2
  716.  
  717. /* Make sure that the following structures are packed, using whatever mechanism
  718.   your compiler defines. */
  719. #pragma pack(1)
  720.  
  721. /* Typedefs to define the return data from a stat call. */
  722. typedef struct {
  723.     short int   recordLength;
  724.     short int   pageSize;
  725.     short int   indexCount;
  726.     long  int   recordTotal;
  727.     short int   fileFlags;
  728.     char        reserved[2];
  729.     short int   preAlloc;
  730. } STATS;
  731.  
  732. /* typedefs needed for CREATE operation */
  733. typedef struct {
  734.     short int   keyPosition;
  735.     short int   keyLength;
  736.     short int   keyFlag;
  737.     long  int   keyTotal;
  738.     char        keyType;
  739.     char        nullValue;
  740.     char        rsvp[4];
  741. } KEY_SPEC;
  742. typedef struct {
  743.     short int   recordLength;
  744.     short int   pageSize;
  745.     short int   indexCount;
  746.     long int    unused;
  747.     short int   fileFlags;
  748.     short int   reserved;
  749.     short int   allocation;
  750. } FILE_SPEC;
  751.  
  752. /*  typedefs needed for EXTENEDED operations */
  753. typedef struct
  754.     {
  755.     char        dataType;
  756.     short int   fieldLength;
  757.     short int   fieldOffset;
  758.     char        comparisonCode;
  759.     char        andOrExpression;
  760.     union
  761.         {
  762.         int     Offset;
  763.         char    Value[2];
  764.         } field2;
  765.     }
  766.     FILTER_TERM;
  767. typedef struct
  768.     {
  769.     short int   bufferLength;
  770.     char        command[2];
  771.     short int   maxSkip;
  772.     short int   termCount;
  773.     }
  774.     FILTER_HEAD;
  775. typedef struct
  776.     {
  777.     short int   recordCount;
  778.     short int   fieldCount;
  779.     }
  780.     FILTER_TAIL;
  781. typedef struct
  782.     {
  783.     short int   fieldLength;
  784.     short int   fieldOffset;
  785.     }
  786.     FILTER_FIELD;
  787. #endif
  788.  
  789.  
  790.